package com.itany.shop.dao.impl;

import com.itany.shop.dao.OrderDao;
import com.itany.shop.entity.Item;
import com.itany.shop.entity.Order;
import com.itany.shop.entity.Product;
import com.itany.shop.entity.User;
import com.itany.shop.exception.DataAccessException;
import com.itany.shop.factory.ObjectFactory;
import com.itany.shop.rowmapper.OrderRowMapper;
import com.itany.shop.util.*;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

/**
 * @Author:石小俊
 * @Date: 2022/12/21 9:04
 * @Version:1.0-SNAPSHOT
 * @Description:
 */
public class OrderDaoImpl implements OrderDao {

    private JDBCTemplate jdbcTemplate = (JDBCTemplate) ObjectFactory.getObject("jdbc");

    @Override
    public Integer insertReturnPrimaryKey(Order order) {
        KeyHolder keyHolder = new KeyHolder();
        jdbcTemplate.update(new PreparedStatementCreator() {
            @Override
            public PreparedStatement createPreparedStatement(Connection conn) throws Exception {
                String sql = new StringBuffer()
                        .append(" insert into ")
                        .append(" t_order ")
                        .append("   (no,price,user_id)")
                        .append(" values ")
                        .append("   (?,?,?)")
                        .toString();
                // 设置保存返回主键
                PreparedStatement ps = conn.prepareStatement(sql,PreparedStatement.RETURN_GENERATED_KEYS);
                ps.setString(1,order.getNo());
                ps.setDouble(2,order.getPrice());
                ps.setInt(3,order.getUser().getId());
                return ps;
            }
        },keyHolder);
        return keyHolder.getKey();
    }

    @Override
    public List<Order> selectByUserId(Integer id) {
        String sql = new StringBuffer()
                .append(" select id,no,price,user_id ")
                .append(" from t_order ")
                .append(" where user_id = ? ")
                .toString();
        List<Order> orders = jdbcTemplate.query(sql,new OrderRowMapper(),id);
        return orders;
    }

    @Override
    public Order selectDetailById(Integer id) {
        String sql = new StringBuffer()
                .append("select o.id,u.username,o.no,p.name,i.num,i.price,o.price 'o.price', ")
                .append(" (select count(1) from t_item where order_id = o.id) count ")
                .append(" from t_order o ")
                .append(" join t_user u ")
                .append("   on o.user_id = u.id ")
                .append(" join t_item i ")
                .append("   on i.order_id = o.id ")
                .append(" join t_product p ")
                .append("   on i.product_id = p.id ")
                .append(" where o.id = ? ")
                .toString();
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        Order order = null;
        try {
            conn = JDBCUtil.getConnection();
            ps = conn.prepareStatement(sql);
            ps.setInt(1,id);
            rs = ps.executeQuery();
            while(rs.next()){
                // 映射需要区分当前是一方的数据还是多方的数据
                // 一方的数据只映射一次
                // 当order为null时,说明尚未映射过
                // 如果order不为null,说明已经映射过了,不再需要映射
                if(null == order) {
                    order = new Order();
                    order.setId(rs.getInt("id"));
                    order.setPrice(rs.getDouble("o.price"));
                    order.setNo(rs.getString("no"));
                    order.setCount(rs.getInt("count"));
                    User user = new User();
                    user.setUsername(rs.getString("username"));
                    order.setUser(user);
                }
                // 多方数据映射多次
                Item item = new Item();
                item.setPrice(rs.getDouble("price"));
                item.setNum(rs.getInt("num"));
                Product product = new Product();
                product.setName(rs.getString("name"));
                item.setProduct(product);

                // 将多方数据加入到一方数据的集合属性中
                // 即:将明细数据交给订单对象的items属性
                order.addItem(item);
            }
            return order;
        } catch (SQLException e) {
            throw new DataAccessException("数据访问异常");
        }
    }
}
